package net.chrone.tpsdk.quartz.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

/**
 * FTP文件上传下载工具类
 */
public class FTPUtil {

	private final FTPClient ftpClient;

	public FTPUtil(String server, int port, String user, String password) throws RuntimeException{
		ftpClient = new FTPClient();
		try {
			ftpClient.connect(server, port);
			showServerReply(ftpClient);
			boolean success = ftpClient.login(user, password);
			if (!success) {
				System.out.println("登陆FTP服务器失败");
				throw new RuntimeException("登陆FTP服务器失败");
			} else {
				System.out.println("登陆FTP服务器成功");
			}
		} catch (IOException e) {
			throw new RuntimeException("连接FTP服务器异常", e);
		}
	}
	
	/**
	 * 文件下载
	 * @param remoteFile
	 * @param localFile
	 * @throws RuntimeException
	 */
	public void downloadSingleFile(String remoteFile, String localFile) throws RuntimeException{
		
		File file = new File(localFile);
		File parentDir = file.getParentFile();
		if(!parentDir.exists()) {
			parentDir.mkdirs();
		}
		try {
			ftpClient.enterLocalPassiveMode();
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
			OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
			boolean success = ftpClient.retrieveFile(remoteFile, outputStream);
			outputStream.close();
			if(success) {
				System.out.println(remoteFile+"文件下载成功");
			}
		} catch (IOException e) {
			throw new RuntimeException("文件下载异常", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.logout();
					ftpClient.disconnect();
				} catch (IOException ex) {
					throw new RuntimeException("关闭FTP连接异常", ex);
				}
			}
		}
	}
	
	/**
	 * Download a whole directory from a FTP server.
	 * @param ftpClient an instance of org.apache.commons.net.ftp.FTPClient class.
	 * @param parentDir Path of the parent directory of the current directory being downloaded.
	 * @param currentDir Path of the current directory being downloaded.
	 * @param saveDir path of directory where the whole remote directory will be downloaded and saved.
	 * @throws IOException if any network or IO error occurred.
	 */
	public void downloadDirectory(String parentDir, String currentDir, String saveDir) throws IOException {
	
		String dirToList = parentDir;
		if (currentDir!=null && !"".equals(currentDir)) {
			dirToList += "/" + currentDir;
		}
		FTPFile[] subFiles = ftpClient.listFiles(dirToList);
		if (subFiles != null && subFiles.length > 0) {
			for (FTPFile subFile : subFiles) {
				String currentFileName = subFile.getName();
				if (currentFileName.equals(".") || currentFileName.equals("..")) {
					// skip parent directory and the directory itself
					continue;
				}
				String filePath = parentDir + "/" + currentDir + "/"
						+ currentFileName;
				if (currentDir.equals("")) {
					filePath = parentDir + "/" + currentFileName;
				}
				String newDirPath = saveDir + parentDir + File.separator
						+ currentDir + File.separator + currentFileName;
				if (currentDir.equals("")) {
					newDirPath = saveDir + parentDir + File.separator
							+ currentFileName;
				}
				if (subFile.isDirectory()) {
					// create the directory in saveDir
					File newDir = new File(newDirPath);
					newDir.mkdirs();
					// download the sub directory
					downloadDirectory(dirToList, currentFileName, saveDir);
				} else {
					// download the file
					downloadSingleFile(filePath, newDirPath);
				}
			}
		}
	}
	
	/**
	 * 文件上传
	 * @param remoteFile
	 * @param localFile
	 * @throws RuntimeException
	 */
	public void uploadFile(String remoteFile, String localFile) throws RuntimeException{
		
		try {
			ftpClient.enterLocalPassiveMode();
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
			
			InputStream inputStream = new FileInputStream(localFile);
            boolean success = ftpClient.storeFile(remoteFile, inputStream);
            inputStream.close();
			if(success) {
				System.out.println(remoteFile+"文件上传成功");
			}
		} catch (IOException e) {
			throw new RuntimeException("文件上传异常", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.logout();
					ftpClient.disconnect();
				} catch (IOException ex) {
					throw new RuntimeException("关闭FTP连接异常", ex);
				}
			}
		}
	}
	
	/**
	 * 显示连接FTP服务器信息
	 * @param ftpClient
	 */
	private static void showServerReply(FTPClient ftpClient) {
		String[] replies = ftpClient.getReplyStrings();
		if (replies != null && replies.length > 0) {
			for (String reply : replies) {
				System.out.println("FTP服务器应答: " + reply);
			}
		}
	}
	
}
